package in.muton.edushare.pages.cp.courseFBCP;

import in.muton.edushare.components.autocomplete.EdushareTextArea;
import in.muton.edushare.pages.common.EdusharePanel;
import in.muton.edushare.poll.panels.SummaryPanel;
import in.muton.edushare.processing.objects.CourseDataHandler;
import in.muton.edushare.wicket.models.CayenneList;
import in.muton.edushare.wicket.models.CayenneModel;
import in.muton.edushare.wicket.models.InnerList;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import com.edushare.common.dao.CourseInstancesDAO;
import com.edushare.common.dao.CoursesDAO;
import com.edushare.common.dao.PollsDAO;
import com.edushare.common.dao.UserPollDAO;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.Courses;
import com.edushare.common.vo.Poll;
import com.edushare.common.vo.Universities;
import com.edushare.common.vo.UserPoll;
import com.edushare.common.vo.Users;

/*
 * Depending on whether the current poll is a child poll or parent poll,
 * apply settings to this poll or all polls of this family.
 * 
 * Settings include:
 * 		1. More course select(only for parent poll).
 * 		2. Add people as reviewers(both parent and poll).
 * 		3. Option to invite faculty as reviewers.
 */

public class PollSettingsPanel extends EdusharePanel {
	private static final long serialVersionUID = -4558802350899212850L;

	private IModel<Universities> univModel = null;
	private boolean isParent = false;
	private boolean inviteFacMem = false;
	private String addlReviewers = "";
	CayenneList<CourseInstances> cInst = new CayenneList<CourseInstances>(null);
	CayenneList<Poll> superList = new CayenneList<Poll>(null);
	private HashMap<IModel<CourseInstances>, Boolean> selection = new HashMap<IModel<CourseInstances>, Boolean>();
	private CourseFeedbackPage page;
	private IModel<Poll> pollModel;

	public PollSettingsPanel(String id, IModel<Universities> univModel,
			final IModel<Poll> pollModel, final CourseFeedbackPage page,
			boolean isParent) {
		super(id, univModel, page);
		this.univModel = univModel;
		this.isParent = isParent;
		this.page = page;
		this.pollModel = pollModel;

		WebMarkupContainer wmc = new WebMarkupContainer("parentDesc") {
			private static final long serialVersionUID = 7197892680419955576L;

			@Override
			public boolean isVisible() {
				return PollSettingsPanel.this.isParent;
			}
		};
		add(wmc);
		wmc.add(new Label("courseNum", new Model<String>() {
			private static final long serialVersionUID = -661242616251392726L;

			@Override
			public String getObject() {
				return getParentAndChildrenPolls().size() + "";
			}
		}));

		wmc.add(new ListView<IModel<Poll>>("courseNamesLV",
				new InnerList<Poll>() {
					private static final long serialVersionUID = -7161030573592739431L;

					@Override
					public List<IModel<Poll>> getObject() {
						return getParentAndChildrenPolls();
					}
				}) {
			@Override
			protected void populateItem(final ListItem<IModel<Poll>> arg0) {
				Link<Void> l;
				arg0.add(l = new Link<Void>("courseLink") {
					@Override
					public void onClick() {
						page.setActivePollModel(arg0.getModelObject());
						page.setParent(false);
						page
								.setActivePanel(CourseFeedbackPage.SHOW_POLL_SETTINGS);
					}

					private static final long serialVersionUID = -4470481711360445565L;
				});
				Poll p = arg0.getModelObject().getObject();
				String courseName = "";
				if (p.getPollGroupId() != null) {
					CourseInstances cinst = new CourseInstancesDAO(
							getORMInterface()).getCourseInstanceById(p
							.getPollGroupId());
					courseName = cinst.getName();
				} else {
					courseName = "Course not set for this poll";
				}
				l.add(new Label("courseName", courseName));
			}

			@Override
			public boolean isVisible() {
				return PollSettingsPanel.this.isParent;
			}

			private static final long serialVersionUID = 5452978006896646946L;
		});

		add(new Label("pollName", pollModel.getObject().getPollName()));
		add(new SummaryPanel("summaryPanel", pollModel, page) {
			private static final long serialVersionUID = 443584200114192040L;

			@Override
			public boolean isVisible() {
				return !PollSettingsPanel.this.isParent;
			}
		});

		Form<Void> f = new Form<Void>("courseSelect") {
			@Override
			public void onSubmit() {
				for (IModel<CourseInstances> cinst : initCourses().getObject()) {
					if (selection.get(cinst) == true)
						activateCourses(pollModel, cinst);
					selection.put(cinst, false);
				}
				if (inviteFacMem == true) {
					setFacultyReviewers(pollModel);
				}
				cInst.getObject().clear();
			}

			private static final long serialVersionUID = 6540990728055153129L;
		};
		add(f);

		f.add(new Label("pName2", pollModel.getObject().getPollName()));
		wmc = new WebMarkupContainer("parentPanel") {
			private static final long serialVersionUID = 571109319545999458L;

			@Override
			public boolean isVisible() {
				return PollSettingsPanel.this.isParent;
			}
		};
		f.add(wmc);
		wmc.add(new Label("pName1", pollModel.getObject().getPollName()));
		f.add(new CheckBox("inviteFacMem", new PropertyModel<Boolean>(this,
				"inviteFacMem")));
		f.add(new EdushareTextArea("addlReviewers", new PropertyModel<String>(
				this, "addlReviewers")));
		wmc.add(new ListView<IModel<CourseInstances>>("courseSelectLV",
				new InnerList<CourseInstances>() {
					private static final long serialVersionUID = 3579417789763018486L;

					@Override
					public List<IModel<CourseInstances>> getObject() {
						return initCourses().getObject();
					}
				}) {
			private static final long serialVersionUID = -8244953001542073623L;

			@Override
			protected void populateItem(
					final ListItem<IModel<CourseInstances>> arg0) {
				arg0.add(new CheckBox("courseSelect", new Model<Boolean>() {
					@Override
					public void setObject(Boolean obj) {
						selection.put(arg0.getModelObject(), obj);
					}

					@Override
					public Boolean getObject() {
						return selection.get(arg0.getModelObject());
					}

					private static final long serialVersionUID = -553952989932024644L;
				}));
				arg0.add(new Label("courseName", arg0.getModelObject()
						.getObject().getName()));
			}

			@Override
			public boolean isVisible() {
				return PollSettingsPanel.this.isParent;
			}
		});
	}

	public CayenneList<CourseInstances> initCourses() {
		if(cInst.getObject().size() != 0)
			return cInst;
		List<CourseInstances> courseList = new ArrayList<CourseInstances>();
		CourseInstancesDAO cDAO = new CourseInstancesDAO(getORMInterface());
		List<Courses> courses = new CoursesDAO(getORMInterface())
				.getUnivCourses(univModel.getObject());
		List<Poll> pList = new ArrayList<Poll>();
		if(isParent){
			pList.add(pollModel.getObject());
			pList.addAll(pollModel.getObject().getChildrenPolls());
		}
		List<Courses> coursesWithPolls = new ArrayList<Courses>();
		for(Poll p:pList){
			if(p.getPollGroupType()!= null && p.getPollGroupType()==Poll.POLL_COURSE){
				CourseInstances ci = cDAO.getCourseInstanceById(p.getPollGroupId());
				if(ci!=null)
					coursesWithPolls.add(ci.getCourse());
			}
		}
		for(Courses c:coursesWithPolls){
			courses.remove(c);
		}
		for(Courses c:courses){
			CourseInstances cinst = cDAO.getActiveInst(c);
			if(cinst != null)
				courseList.add(cinst);
		}
		selection.clear();
		cInst.add(courseList);
		for(IModel<CourseInstances> ci : cInst.getObject()){
			selection.put(ci, false);
		}
		return cInst;
	}

	private List<IModel<Poll>> getParentAndChildrenPolls() {
		superList.getObject().clear();
		if (page.getActivePollModel().getObject().getPollGroupId() != null) {
			superList.add(page.getActivePollModel());
			if (isParent)
				superList.add(page.getActivePollModel().getObject()
						.getChildrenPolls());
		}
		return superList.getObject();
	}

	private void activateCourses(IModel<Poll> pollModel,
			IModel<CourseInstances> cInst) {
		PollsDAO pDAO = new PollsDAO(getORMInterface());
		Poll p = pollModel.getObject();
		if (p.getPollGroupId() != null) {
			Poll parent = p;
			p = pDAO.createNewPoll(parent);
			pDAO.copyPollQuestions(p, parent);
		}
		p.setPollGroupId(cInst.getObject().getCourseInstanceId());
		p.setPollGroupType(Poll.POLL_COURSE);
		p.setPollSubgroup(Poll.POLL_STUDENTS);
		p.setStatus(Poll.POLL_STATUS_POLLING);
		CourseDataHandler cdh = new CourseDataHandler(cInst);
		new UserPollDAO(getORMInterface()).addUsersToPoll(cdh.getStudents()
				.getUtilList(), p, UserPoll.ROLE_RESPONDENT);
		getORMInterface().commitAllChanges();
	}

	private void inviteReviewers(IModel<Poll> pollModel) {

	}

	private void setFacultyReviewers(IModel<Poll> pollModel) {
		List<Poll> list = new ArrayList<Poll>();
		if (isParent) {
			Poll p = pollModel.getObject();
			if (p.getParentPoll() != null) {
				Poll parent = p.getParentPoll();
				list.add(parent);
				list.addAll(parent.getChildrenPolls());
			}
		} else {
			list.add(pollModel.getObject());
		}

		for (Poll p : list) {
			CourseInstancesDAO cDAO = new CourseInstancesDAO(getORMInterface());
			CourseInstances cinst = cDAO.getCourseInstanceById(p
					.getPollGroupId());
			CourseDataHandler cdh = new CourseDataHandler(
					new CayenneModel<CourseInstances>(cinst));
			CayenneList<Users> fac = cdh.getTeachers();
			new UserPollDAO(getORMInterface()).addUsersToPoll(
					fac.getUtilList(), p, UserPoll.ROLE_REVIEWER);
		}
	}

	public boolean isInviteFacMem() {
		return inviteFacMem;
	}

	public void setInviteFacMem(boolean inviteFacMem) {
		this.inviteFacMem = inviteFacMem;
	}

	public void setAddlReviewers(String addlReviewers) {
		this.addlReviewers = addlReviewers;
	}

	public String getAddlReviewers() {
		return addlReviewers;
	}
}
